﻿using System;
using System.ComponentModel;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media.Animation;
using MyTime.Core.Entities;
using MyTime.ProviderFactory;
using MyTime.WPF.Core;
using WinForms = System.Windows.Forms;


namespace MyTime.WPF
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        private readonly WinForms.NotifyIcon _notifier = new WinForms.NotifyIcon();
        private readonly TimeTracker _timeTracker;
        private double _aniTime = 0.2;
        private bool _isClosing;
        private bool _isVisible;
        private string _localizedQuestionText = "Vad gör du?";

        private SummaryWindow _summary;

        public MainWindow()
        {
            InitializeComponent();
            _timeTracker = new TimeTracker(Assembly.GetExecutingAssembly().Location);
            //_timeTracker.Interval = 2;
            SetupAllEvents();

            //set up context menu
            _notifier.MouseDown += notifier_MouseDown;
            _notifier.Icon = Properties.Resources.time;
            _notifier.Visible = true;

            //set up settings
            SettingsGrid.Visibility = Visibility.Collapsed;
            CloseBtn.Visibility = Visibility.Collapsed;
            AutostartChckBox.IsChecked = _timeTracker.AutoStart;
            IntervalTxtBox.Text = _timeTracker.Interval.ToString();
        }

        private SummaryWindow Summary
        {
            get
            {
                if (_summary == null || !_summary.IsActive)
                    _summary = new SummaryWindow(_timeTracker);
                return _summary;
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        public event SessionEndingCancelEventHandler SessionEnding;

        /// <summary>
        /// Will hook up all events (anonymous)
        /// </summary>
        private void SetupAllEvents()
        {
            //event for popup
            _timeTracker.TimeToReport += (sender, e) => Dispatcher.Invoke((() =>
                                                                               {
                                                                                   CloseBtn.Visibility =
                                                                                       Visibility.Collapsed;
                                                                                   SettingsGrid.Visibility =
                                                                                       Visibility.Collapsed;

                                                                                   this.FadeIn(_aniTime);
                                                                                   _isVisible = true;
                                                                               }));
            //event is thrown when user is away or doesn't supply input
            _timeTracker.TimeOut += (sender, e) => Dispatcher.Invoke((() =>
                                                                          {
                                                                              if (_isVisible)
                                                                                  _timeTracker.ReportTime(
                                                                                      whatImDoingTxtBox.Text,
                                                                                      DateTime.Now, DateTime.Now);
                                                                          }));
            //close the final row on application exit
            Closing += (sender, e) =>
                           {
                               _isClosing = true;
                               _timeTracker.ReportTime(whatImDoingTxtBox.Text, DateTime.Now, DateTime.Now);
                           };
            SessionEnding += (sender, e) =>
                                 {
                                     if (!_isClosing)
                                         _timeTracker.ReportTime(whatImDoingTxtBox.Text, DateTime.Now, DateTime.Now);
                                 };
        }

        private void notifier_MouseDown(object sender, WinForms.MouseEventArgs e)
        {
            if (e.Button != WinForms.MouseButtons.Right)
                return;

            var menu = (ContextMenu) FindResource("NotifierContextMenu");
            menu.IsOpen = true;
        }

        private void whatImDoingTxtBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key != Key.Enter || string.IsNullOrWhiteSpace(whatImDoingTxtBox.Text))
                return;

            DateTime d = DateTime.Now;
            _timeTracker.ReportTime(whatImDoingTxtBox.Text, d);
            this.FadeOut(_aniTime);
            _isVisible = false;
            Summary.Close();
        }

        private void whatImDoingTxtBox_GotFocus(object sender, RoutedEventArgs e)
        {
            if (whatImDoingTxtBox.Text == _localizedQuestionText)
                whatImDoingTxtBox.Text = "";
        }

        private void sourceFileBrowserBtn_Click(object sender, RoutedEventArgs e)
        {
            var dia = new WinForms.OpenFileDialog();
            if (dia.ShowDialog() != WinForms.DialogResult.OK)
                return;

            var bgWorker = new BackgroundWorker();
            BrowseSrcBtn.Visibility = Visibility.Collapsed;
            ProgBar.Visibility = Visibility.Visible;
            var duration = new Duration(TimeSpan.FromSeconds(1));
            var doubleanimation = new DoubleAnimation(100.0, duration);
            doubleanimation.RepeatBehavior = RepeatBehavior.Forever;
            ProgBar.BeginAnimation(RangeBase.ValueProperty, doubleanimation);
            bgWorker.DoWork += (o, s) => Instance.Current.ImportOldData(1, dia.FileName);
            bgWorker.RunWorkerCompleted += (_o, _) =>
                                               {
                                                   ProgBar.Visibility = Visibility.Collapsed;
                                                   BrowseSrcBtn.Visibility = Visibility.Visible;
                                               };
            bgWorker.RunWorkerAsync();
        }

        /// <summary>
        /// Save
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SaveBtn_Click(object sender, RoutedEventArgs e)
        {
            //interval
            double o = _timeTracker.Interval;
            if (double.TryParse(IntervalTxtBox.Text, out o))
                _timeTracker.Interval = o;

            //autostart
            bool c;
            if (bool.TryParse(AutostartChckBox.IsChecked.ToString(), out c))
                _timeTracker.AutoStart = c;
            this.FadeOut(_aniTime);
        }

        //Contextmenu click events
        private void MenuItemSummary_Click(object sender, RoutedEventArgs e)
        {
            Summary.FadeIn(_aniTime);
            Summary.Focus();
        }

        private void MenuItemReportNow_Click(object sender, RoutedEventArgs e)
        {
            SettingsGrid.Visibility = Visibility.Collapsed;
            CloseBtn.Visibility = Visibility.Collapsed;
            whatImDoingTxtBox.Text = "";
            whatImDoingTxtBox.Visibility = Visibility.Visible;
            this.FadeIn(_aniTime);
        }

        private void MenuItemSettings_Click(object sender, RoutedEventArgs e)
        {
            SettingsGrid.Visibility = Visibility.Visible;
            CloseBtn.Visibility = Visibility.Visible;
            whatImDoingTxtBox.Visibility = Visibility.Collapsed;
            this.FadeIn(_aniTime);
        }

        private void MenuItemExit_Click(object sender, RoutedEventArgs e)
        {
            this.FadeOut(_aniTime);
            MessageBoxResult res = MessageBox.Show("Are you sure you want to exit", "MyTime", MessageBoxButton.YesNo,
                                                   MessageBoxImage.Question);
            if (res == MessageBoxResult.Yes)
                Application.Current.Shutdown();
        }

        private void CloseBtn_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.FadeOut(_aniTime);
        }

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }

        #region Nested type: UpdateUI

        protected delegate void UpdateUI();

        #endregion
    }
}